package net.sansi.v3correctserver.task;

import cn.hutool.extra.spring.SpringUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.sansi.v3correctserver.constenum.AppHelper;
import net.sansi.v3correctserver.dto.correctresult.CorrectResultDto;
import net.sansi.v3correctserver.dto.v3serverapi.V3ServerCorrectDto;
import net.sansi.v3correctserver.entity.screen.ScanBoard;
import net.sansi.v3correctserver.entity.space.CorrectCnf;
import net.sansi.v3correctserver.exception.ServiceException;
import net.sansi.v3correctserver.service.correctresult.CorrectResultService;
import net.sansi.v3correctserver.service.space.ProjectSpace;
import net.sansi.v3correctserver.service.v3serverapi.V3ServerCorrectApi;
import net.sansi.v3correctserver.util.CmmUtil;

import java.nio.file.Path;
import java.util.List;

/**
 * Created by Fang
 * create time : 2024/11/11
 * IDE : IntelliJ IDEA
 */

@Slf4j
public class UploadFactorTask extends V3Task<UploadFactorTask,
        UploadFactorTask.Progress> {

    private final CorrectResultDto.StartUploadFactorReq params;
    private final List<ScanBoard> scanBoards;
    private final ProjectSpace projectSpace;
    private final CorrectCnf correctCnf;
    private final V3ServerCorrectApi v3ServerCorrectApi;

    public UploadFactorTask(CorrectResultDto.StartUploadFactorReq params, List<ScanBoard> scanBoards) {
        super(5, new Progress());
        this.params = params;
        this.scanBoards = scanBoards;
        projectSpace = AppHelper.projectSpace();
        correctCnf = projectSpace.getCorrectCnf();
        v3ServerCorrectApi = SpringUtil.getBean(V3ServerCorrectApi.class);
    }

    @Override
    void runHandler() {
        mock();
    }

    /**
     * 模拟上传系数
     */
    private void mock() {
        for (int i = 0; i <= 100; i++) {
            CmmUtil.sleep(200);
            progress.setProgress((double) i);
        }
    }

    /**
     * 上传系数
     * 分辨是CF还是CL
     * 1. CF 上传CF
     * 2. CL 上传CL
     */
    private void upload() {
        switch (params.getFactorType()) {
            case CorrectResultService.FACTOR_TYPE_CF:
                uploadCF();
                break;
            case CorrectResultService.FACTOR_TYPE_CL:
                uploadCL();
                break;
            default:
                throw new ServiceException("非法请求");
        }
    }

    interface GetProgress {
        V3ServerCorrectDto.UpgradeProgressResp get();
    }

    /**
     * 上传CL
     */
    private void uploadCL() {
        Path path = projectSpace.factorCLZip();
        v3ServerCorrectApi.uploadClFile(correctCnf.getScreenId(),
                CmmUtil.convertToMultipartFile(path.toFile())
        );
        v3ServerCorrectApi.uploadClStart(correctCnf.getScreenId());
        refreshProgress(() -> v3ServerCorrectApi.getCLUpgradeProgress(correctCnf.getScreenId()));
    }

    /**
     * 上传CF
     */
    private void uploadCF() {
        Path path = projectSpace.factorCFZip();
        v3ServerCorrectApi.uploadCFFile(
                CmmUtil.convertToMultipartFile(path.toFile())
        );
        v3ServerCorrectApi.uploadCFStart(correctCnf.getScreenId());
        refreshProgress(() -> v3ServerCorrectApi.getCFUpgradeProgress(correctCnf.getScreenId()));
    }

    /**
     * 刷新进度
     *
     * @param getProgress 获取进度的方法
     */
    private void refreshProgress(GetProgress getProgress) {
        long start = System.currentTimeMillis();
        while (true) {
            V3ServerCorrectDto.UpgradeProgressResp resp = getProgress.get();
            progress.setProgress(Double.valueOf(resp.getScreenProgress().getProgress()));
            progress.setUploadStatus(resp.getScreenProgress().getStatus());
            if (resp.getScreenProgress().getStatus().equals("success")) break;
            CmmUtil.sleep(1000);
            if (System.currentTimeMillis() - start > 1000 * 60 * 5) {
                throw new ServiceException("上传超时");
            }
        }
    }

    @Getter
    @Setter
    @ApiModel("上传系数进度")
    public static class Progress extends V3Task.Progress {

        @ApiModelProperty("进度")
        private Double progress = 0d;

        @ApiModelProperty("状态")
        private String uploadStatus = "";
    }

}
